    //
//  HttpRequestV2.m
//  LimitFreeMaster
//
//  Created by tanghaibo on 12-12-18.
//  last Modified by zhangtie  13-11-19
//

#import "QBHttpRequest.h"
#import "OpenUDID.h"
@interface QBHttpRequest()
{
}
@end

@implementation QBHttpRequest

- (void)dealloc
{
    [self releaseSelfBlocksOnMainThread];
    [super dealloc];
}

- (void)clearDelegatesAndCancel
{
    [super clearDelegatesAndCancel];
    [self releaseSelfBlocksOnMainThread];
}

+ (QBHttpRequest *)requestWithURLStr:(NSString *)initURLString
                               param:(NSDictionary *)param
                          httpMethod:(HttpMethod)httpMethod
                              isAsyn:(BOOL)isAsyn
                     completionBlock:(ASIRequsetBlock)aCompletionBlock
                         failedBlock:(ASIRequsetBlock)aFailedBlock{
    
    return [self requestWithURLStr:initURLString
                             param:param
                        httpMethod:httpMethod
                            isAsyn:isAsyn
                          userInfo:nil
                      successBlock:nil
                       failedBlock:aFailedBlock
                   completionBlock:aCompletionBlock];

}

+ (QBHttpRequest *)requestWithURLStr:(NSString *)initURLString
                               param:(NSDictionary *)param
                          httpMethod:(HttpMethod)httpMethod
                              isAsyn:(BOOL)isAsyn
                            postJson:(BOOL)postJson
                     completionBlock:(ASIRequsetBlock)aCompletionBlock
                         failedBlock:(ASIRequsetBlock)aFailedBlock
{
    return [self requestWithURLStr:initURLString
                             param:param
                        httpMethod:httpMethod
                           timeOut:30
                            isAsyn:isAsyn
                          postJson:postJson
                          userInfo:nil
                      successBlock:nil
                       failedBlock:aFailedBlock
                   completionBlock:aCompletionBlock];
}

+ (QBHttpRequest*)requestWithURLStr:(NSString *)initURLString
                              param:(NSDictionary *)param
                         httpMethod:(HttpMethod)httpMethod
                             isAsyn:(BOOL)isAsyn
                       successBlock:(ASIRequsetBlock)aSuccessBlock
                        failedBlock:(ASIRequsetBlock)aFailedBlock
{
    return [self requestWithURLStr:initURLString
                             param:param
                        httpMethod:httpMethod
                            isAsyn:isAsyn
                          userInfo:nil
                      successBlock:aSuccessBlock
                       failedBlock:aFailedBlock];
}

+ (QBHttpRequest*)requestWithURLStr:(NSString *)initURLString
                              param:(NSDictionary *)param
                         httpMethod:(HttpMethod)httpMethod
                             isAsyn:(BOOL)isAsyn
                           userInfo:(NSDictionary*)userInfo
                       successBlock:(ASIRequsetBlock)sucessReqBlock
                        failedBlock:(ASIRequsetBlock)aFailedReqBlock
{
    return [self requestWithURLStr:initURLString
                             param:param
                        httpMethod:httpMethod
                            isAsyn:isAsyn
                          userInfo:userInfo
                      successBlock:sucessReqBlock
                       failedBlock:aFailedReqBlock
                   completionBlock:nil];
}

+ (QBHttpRequest*)requestWithURLStr:(NSString *)initURLString
                              param:(NSDictionary *)param
                         httpMethod:(HttpMethod)httpMethod
                             isAsyn:(BOOL)isAsyn
                           userInfo:(NSDictionary*)userInfo
                       successBlock:(ASIRequsetBlock)sucessReqBlock
                        failedBlock:(ASIRequsetBlock)aFailedReqBlock
                    completionBlock:(ASIRequsetBlock)aCompletionBlock
{

    return [self requestWithURLStr:initURLString
                             param:param
                        httpMethod:httpMethod
                           timeOut:30
                            isAsyn:isAsyn
                          userInfo:userInfo
                      successBlock:sucessReqBlock
                       failedBlock:aFailedReqBlock
                   completionBlock:aCompletionBlock];
}

+ (QBHttpRequest*)requestWithURLStr:(NSString *)initURLString
                              param:(NSDictionary *)param
                         httpMethod:(HttpMethod)httpMethod
                            timeOut:(NSTimeInterval)timeOut
                             isAsyn:(BOOL)isAsyn
                           userInfo:(NSDictionary*)userInfo
                       successBlock:(ASIRequsetBlock)sucessReqBlock
                        failedBlock:(ASIRequsetBlock)aFailedReqBlock
                    completionBlock:(ASIRequsetBlock)aCompletionBlock
{
    return [self requestWithURLStr:initURLString
                             param:param
                        httpMethod:httpMethod
                           timeOut:30
                            isAsyn:isAsyn
                          postJson:NO
                          userInfo:userInfo
                      successBlock:sucessReqBlock
                       failedBlock:aFailedReqBlock
                   completionBlock:aCompletionBlock];
}
+ (QBHttpRequest*)requestWithURLStr:(NSString *)initURLString
                              param:(NSDictionary *)param
                         httpMethod:(HttpMethod)httpMethod
                            timeOut:(NSTimeInterval)timeOut
                             isAsyn:(BOOL)isAsyn
                           postJson:(BOOL)postJons
                           userInfo:(NSDictionary*)userInfo
                       successBlock:(ASIRequsetBlock)sucessReqBlock
                        failedBlock:(ASIRequsetBlock)aFailedReqBlock
                    completionBlock:(ASIRequsetBlock)aCompletionBlock



{
    QBHttpRequest *aRequest = [[[QBHttpRequest alloc] initWithURL:nil] autorelease];
    //不适用长连接 非Keep alive
    [aRequest setShouldAttemptPersistentConnection:NO];
    // https请求，不验证证书的有效性
    [aRequest setValidatesSecureCertificate:NO];
    
    // 设置超时时间
    [aRequest setTimeOutSeconds:timeOut];
    
    // 本地Hack，添加请求头
//    NSDictionary *commonHeader = [[QBHttpRequestHeader shareInstance] commonHeader];
//    [aRequest.requestHeaders addEntriesFromDictionary:commonHeader];
    
    if(postJons)
    {
        
    }
    [aRequest addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"];
    //添加userInfo
    [aRequest setUserInfo:userInfo];
    
    DBLog(@"requestHeaders: %@",aRequest.requestHeaders);
    
#if DEBUG_USEPROXY
    // 设置请求代理
    aRequest.proxyHost = @"127.0.0.1";
    aRequest.proxyPort = 9999;
#endif
    
    
    NSString *requestUrlStr = initURLString;
    if (httpMethod == HttpMethodPost ||
        httpMethod == HttpMethodDelete)
    {
        
        if(postJons)
        {
            [aRequest appendPostData:[[Util convertObjectToJSON:param] dataUsingEncoding:NSUTF8StringEncoding]];
            
        }
        else
        {
            [param enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
             {
                 if ([obj isKindOfClass:[NSURL class]] && [[NSFileManager defaultManager] fileExistsAtPath:[(NSURL*)obj path]])
                 {
                     // 添加上传的文件
                     [aRequest addFile:[(NSURL*)obj path] forKey:key];
                 }
                 else if ([obj isKindOfClass:[UIImage class]])
                 {
                     // 添加上传的图片
                     CGFloat compression = 0.5f;
                     CGFloat maxCompression = 0.1f;
                     int maxFileSize = 450*1024;
                     
                     NSData *imgData = UIImageJPEGRepresentation(obj, compression);
                     while (imgData.length > maxFileSize && compression > maxCompression)
                     {
                         compression -= 0.1;
                         imgData = UIImageJPEGRepresentation(obj, compression);
                     }
                     
                     NSString *fileName =[NSString stringWithFormat:@"%@.jpg", key];
                     [aRequest addData:imgData withFileName:fileName andContentType:@"image/jpg" forKey:key];
                 }
                 else
                 {
                     [aRequest addPostValue:[obj URLEncodedString] forKey:key];
                 }
   
             }];
        }
        
        [aRequest setRequestMethod:(httpMethod == HttpMethodPost)?@"POST":@"DELETE"];
    }
    else if(httpMethod == HttpMethodGet)
    {
        [aRequest setRequestMethod:@"GET"];
        
        NSMutableString *postString = [NSMutableString stringWithCapacity:0];
        [param enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
         {
             if ([obj respondsToSelector:@selector(stringValue)])
             {
                 obj = [obj stringValue];
             }
             if ([obj isKindOfClass:[NSString class]])
             {
                 [postString appendString:[NSString stringWithFormat:@"%@=%@&", key, obj] ];
             }
         }];
        
        NSInteger questLocation = [initURLString rangeOfString:@"?"].location;
        if (NSNotFound!=questLocation)
        {
            requestUrlStr = [NSString stringWithFormat:@"%@%@", initURLString, postString];
        }
        else
        {
            requestUrlStr = [NSString stringWithFormat:@"%@?%@", initURLString, postString];
        }
    }
    else if(httpMethod == HttpMethodunPostAndDelete)
    {
        
        if(postJons)
        {
            [aRequest appendPostData:[[Util convertObjectToJSON:param] dataUsingEncoding:NSUTF8StringEncoding]];
        }
        [aRequest setRequestMethod:@"DELETE_AND_POST"];
        
        
    }
    
    [aRequest setURL:[NSURL URLWithString:requestUrlStr]];
    
    [aRequest setSuccessReqBlock:sucessReqBlock];
    [aRequest setFailedReqBlock:aFailedReqBlock];
    [aRequest setCompletionReqBlock:aCompletionBlock];
    
    if (isAsyn) {
        [aRequest startAsynchronous];
    }else{
        [aRequest startSynchronous];
    }
    
#if DEBUG
    if (httpMethod==HttpMethodGet) {
        DBLog(@"URL:%@", requestUrlStr);
    }else{
        NSString *postStr = [[[NSString alloc] initWithData:aRequest.postBody encoding:NSUTF8StringEncoding] autorelease];
        DBLog(@"URL:%@, params(POST):%@", requestUrlStr, param);
    }
    
#endif
    return aRequest;
}


#if NS_BLOCKS_AVAILABLE
- (void)setCompletionReqBlock:(ASIRequsetBlock)aCompletionBlock{
    [_completionReqBlock release];
	_completionReqBlock = [aCompletionBlock copy];
    
    
}

- (void)setFailedReqBlock:(ASIRequsetBlock)aFailedBlock{
    [_failureReqBlock release];
	_failureReqBlock = [aFailedBlock copy];
    
}

- (void)setSuccessReqBlock:(ASIRequsetBlock)aSuccessBlock
{
    [_successReqBlock release];
	_successReqBlock = [aSuccessBlock copy];
}

- (void)releaseSelfBlocksOnMainThread
{
	NSMutableArray *blocks = [NSMutableArray array];
	if (_completionReqBlock)
    {
		[blocks addObject:_completionReqBlock];
		[_completionReqBlock release];
		_completionReqBlock = nil;
	}
	if (_failureReqBlock)
    {
		[blocks addObject:_failureReqBlock];
		[_failureReqBlock release];
		_failureReqBlock = nil;
	}
    
    if (_successReqBlock)
    {
        [blocks addObject:_successReqBlock];
		[_successReqBlock release];
		_successReqBlock = nil;
    }
	
	[[self class] performSelectorOnMainThread:@selector(releaseSelfBlocks:) withObject:blocks waitUntilDone:[NSThread isMainThread]];
}

+ (void)releaseSelfBlocks:(NSArray*)blocks
{
    
}

#endif


- (void)handleSessionTimeout
{
    // session失效，通知观察者
    DBLog(@"responseHeaders: %@",self.responseHeaders);
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:kNotiSessionTimeout object:nil];
    }
}

- (BOOL)isSessionTimeout
{
    NSString *needTicket = [self.responseHeaders objectForKey:@"needTicket"];
    return (needTicket && [needTicket isEqualToString:@"1"]);
}

- (NSString*)getErrMsg:(NSDictionary*)dict
{
    NSString *errMsg = FAILDMESSAGE;
    if(dict)
    {
        errMsg = getErrMsg(dict);
        if(![errMsg isKindOfClass:[NSNull class]])
        {
            errMsg = (errMsg)?errMsg:FAILDMESSAGE;
        }
        else
        {
            errMsg = FAILDMESSAGE;
        }
    }
    return errMsg;
}

- (void)requestFinishHandle
{
#if NS_BLOCKS_AVAILABLE
    if ([self isSessionTimeout])
    {//session过期
        [self handleSessionTimeout];
    }
    else
    {
        NSDictionary *responseDic   = [Util convertJSONToDict:self.responseString];
        NSMutableDictionary *newDic = [NSMutableDictionary dictionaryWithDictionary:responseDic];
        if(responseDic && isDictWithCountMoreThan0(responseDic))
        {
            NSMutableDictionary *newDic = [NSMutableDictionary dictionaryWithDictionary:responseDic];
            NSInteger  responseCode     = [PUGetObjFromDict(@"responseCode", newDic, [NSNumber class]) integerValue];// [[newDic objectForKey:@"responseCode"] integerValue];
            
            if(responseCode == 1000)
            {//成功请求
                DBLog(@"请求成功");
                if(_successReqBlock)
                    _successReqBlock(self, newDic);
            }
            else
            {//请求回来但是失败
                DBLog(@"请求成功,但是处理异常:%@, url:%@", [self getErrMsg:responseDic], self.url);
                //统一处理错误提示errmsg,交到manager层时候一定不会为空
                [newDic setObject:[self getErrMsg:responseDic] forKey:KEY_ERRORMSG];
                if (responseCode == 1001)
                {
//                    [[QBVersionUpdateManager sharedManager] clientForceUpgrad];
                }
                
                else if (responseCode == 1003)
                {
//                    [[QBVersionUpdateManager sharedManager] clientUpgrad];
                }
                
                else if (responseCode == 1004)
                {
//                    [[QBSessionManager shared] setIsValid:NO];
                }
                
                if(_failureReqBlock)
                {
                    _failureReqBlock(self, newDic);
                }
            }
        }
        else
        {
            [newDic setObject:[self getErrMsg:nil] forKey:KEY_ERRORMSG];
            if(_failureReqBlock)
            {
                _failureReqBlock(self, newDic);
            }
        }
        
        if(_completionReqBlock)
        {
            _completionReqBlock(self, newDic);
        }
    }
#endif
}

- (void)requestFinished
{
    [super requestFinished];
    [self performSelectorOnMainThread:@selector(requestFinishHandle) withObject:nil waitUntilDone:[NSThread isMainThread]];
}

- (void)requestFailedHandle
{
#if NS_BLOCKS_AVAILABLE
    if ([self isSessionTimeout])
    {
        [self handleSessionTimeout];
    }
    
    if(_failureReqBlock)
    {
        //统一处理错误提示errmsg,交到manager层时候一定不会为空
        NSDictionary *responseDic   = [Util convertJSONToDict:self.responseString];
        NSMutableDictionary *newDic = [NSMutableDictionary dictionaryWithDictionary:responseDic];
        SET_PARAM([self getErrMsg:responseDic], KEY_ERRORMSG, newDic);
        _failureReqBlock(self, newDic);
    }
#endif
}

- (void)failWithError:(NSError *)theError
{
    [super failWithError:theError];
    DBLog(@"请求失败：%@", self.url);
    [self performSelectorOnMainThread:@selector(requestFailedHandle) withObject:nil waitUntilDone:[NSThread isMainThread]];
}

#pragma mark - getter/setter
+ (NSDictionary *)commonParams
{
    NSMutableDictionary *commonParams = [NSMutableDictionary dictionaryWithCapacity:0];
//    [commonParams setObject:APP_VERSION forKey:@"version"];
//    [commonParams setObject:APP_DEV forKey:@"devType"];
//    [commonParams setObject:[OpenUDID value] forKey:@"devID"];
//    [commonParams setObject:kUMChannel forKey:@"channel"];
//    
//    [commonParams setObject:[QBUtil deviceString] forKey:@"iOSversion"];
//    [commonParams setObject:@"" forKey:@"userId"];
//    [commonParams setObject:@"" forKey:@"userType"];

    return commonParams;
}

- (NSMutableDictionary*)requestHeaders
{
    if(!requestHeaders)
    {
        requestHeaders = _ALLOC_OBJ_(NSMutableDictionary);
    }
    
    return requestHeaders;
}

@end
